import {
  RectNode,
  RectNodeModel,
  CircleNodeModel,
  CircleNode,
  PolylineEdgeModel,
  PolylineEdge,
  BezierEdge,
  BezierEdgeModel,
  HtmlNode,
  HtmlNodeModel,
  h,
} from '@logicflow/core'

// 贝塞尔曲线边模型 - 带动画效果
class customBezierEdgeModel extends BezierEdgeModel {
  setAttributes() {
    this.isAnimation = true
  }

  getEdgeStyle() {
    const style = super.getEdgeStyle()
    style.strokeWidth = 3
    return style
  }

  getEdgeAnimationStyle() {
    const style = super.getEdgeAnimationStyle()
    style.strokeDasharray = '5 5'
    style.animationDuration = '40s'
    return style
  }
}

// 自定义贝塞尔曲线边视图 - 支持渐变色
class customBezierEdgeView extends BezierEdge {
  getEdge() {
    const { model } = this.props
    const { path, arrowConfig } = model
    const style = model.getEdgeStyle()
    const animationStyle = model.getEdgeAnimationStyle()

    const {
      strokeDasharray,
      strokeDashoffset,
      animationName,
      animationDuration,
      animationIterationCount,
      animationTimingFunction,
      animationDirection,
    } = animationStyle

    // 使用 LogicFlow 的 h 函数创建 SVG 元素
    return h('g', {}, [
      // 创建渐变定义
      h('defs', {}, [
        h(
          'linearGradient',
          {
            id: 'customEdgeGradient',
            x1: '0%',
            y1: '0%',
            x2: '100%',
            y2: '100%',
            gradientUnits: 'userSpaceOnUse',
          },
          [
            h('stop', {
              offset: '0%',
              'stop-color': '#ff6b6b',
            }),
            h('stop', {
              offset: '50%',
              'stop-color': '#4ecdc4',
            }),
            h('stop', {
              offset: '100%',
              'stop-color': '#45b7d1',
            }),
          ],
        ),
      ]),
      // 创建路径
      h('path', {
        d: path,
        ...style,
        ...arrowConfig,
        strokeDasharray,
        stroke: 'url(#customEdgeGradient)',
        fill: 'none',
        style: {
          strokeDashoffset: strokeDashoffset,
          animationName,
          animationDuration,
          animationIterationCount,
          animationTimingFunction,
          animationDirection,
        },
      }),
    ])
  }
}

// 自定义起始节点模型 - 不能被任何连接，只能连接一个出边
class StartEventModel extends CircleNodeModel {
  getConnectedTargetRules() {
    const rules = super.getConnectedTargetRules()
    const notAsTarget = {
      message: '起始节点不能作为边的终点',
      validate: () => false, // 禁止任何连线连接到起始节点
    }
    rules.push(notAsTarget)
    return rules
  }

  getConnectedSourceRules() {
    const rules = super.getConnectedSourceRules()
    const onlyOneOutgoing = {
      message: '起始节点只能连接一个出边',
      validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) => {
        // 获取当前节点作为源节点的所有边
        const edges = this.graphModel.edges
        const outgoingEdges = edges.filter((edge) => edge.sourceNodeId === sourceNode.id)
        // 如果已经有出边了，则不允许再连接
        return outgoingEdges.length === 0
      },
    }
    rules.push(onlyOneOutgoing)
    return rules
  }

  getNodeStyle() {
    const style = super.getNodeStyle()
    style.stroke = '#EA8622'
    return style
  }
}

// 自定义结束节点模型 - 不能连接任何节点
class EndEventModel extends CircleNodeModel {
  getConnectedSourceRules() {
    const rules = super.getConnectedSourceRules()
    const notAsSource = {
      message: '结束节点不能作为边的起点',
      validate: () => false, // 禁止结束节点连接到任何节点
    }
    rules.push(notAsSource)
    return rules
  }
  getNodeStyle() {
    const style = super.getNodeStyle()
    style.stroke = '#22EA29'
    return style
  }
}

// 自定义矩形节点模型 - 不能自连
class SquareModel extends RectNodeModel {
  getConnectedTargetRules() {
    const rules = super.getConnectedTargetRules()
    const noSelfConnect = {
      message: '节点不能连接到自身',
      validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) => {
        return targetNode.id !== sourceNode.id // 禁止连接到自身
      },
    }
    rules.push(noSelfConnect)
    return rules
  }
  getNodeStyle() {
    const style = super.getNodeStyle()
    style.stroke = '#229DEA'
    return style
  }
}

// 自定义Vue节点模型 - 支持进度显示和右键菜单配置
class CustomVueNodeModel extends HtmlNodeModel {
  initNodeData(data: any) {
    super.initNodeData(data)
    this.width = 160
    this.height = 120
  }

  // 重写文本配置，禁用默认文本渲染避免重叠
  getTextStyle() {
    const style = super.getTextStyle()
    // 完全隐藏默认文本，因为我们在自定义HTML中已经显示了
    style.fontSize = 0
    style.color = 'transparent'
    style.display = 'none'
    return style
  }
  // 重写获取文本区域方法，返回空区域避免文本渲染
  getTextShape() {
    return {
      x: this.x,
      y: this.y,
      width: 0,
      height: 0,
    }
  }
  // 完全禁用文本编辑功能
  getEditableStatus() {
    return false
  }
  // 禁用双击编辑文本
  enableTextEdit() {
    return false
  }
  getDefaultAnchor() {
    const { width, height, x, y } = this
    return [
      { x: x - width / 2, y, id: `${this.id}_left` },
      { x: x + width / 2, y, id: `${this.id}_right` },
      { x, y: y - height / 2, id: `${this.id}_top` },
      { x, y: y + height / 2, id: `${this.id}_bottom` },
    ]
  }

  getConnectedTargetRules() {
    const rules = super.getConnectedTargetRules()
    const noSelfConnect = {
      message: '节点不能连接到自身',
      validate: (sourceNode, targetNode, sourceAnchor, targetAnchor) => {
        return targetNode.id !== sourceNode.id
      },
    }
    rules.push(noSelfConnect)
    return rules
  }
}

// 自定义Vue节点视图 - 显示数据但可以正常拖拽
class CustomVueNodeView extends HtmlNode {
  setHtml(rootEl: SVGForeignObjectElement) {
    const { properties } = this.props.model
    const { auditTime, userId, borderColor = '#229DEA', backgroundColor = '#fff' } = properties || {}
    // 根据实际数据计算显示标签
    const auditTimeLabel =
      Array.isArray(auditTime) && auditTime.length === 2 ? `${auditTime[0].substring(0, 10)}~${auditTime[1].substring(0, 10)}` : '随时审核'
    const selectedDataLabel = Array.isArray(userId) && userId.length > 0 ? '已选择' : '默认设置'
    const nodeName = this.props.model.text?.value || this.props.model.text || '自定义节点'
    rootEl.innerHTML = `
      <div class="custom-vue-node" style="
        width: 160px;
        height: 120px;
        border: 2px solid ${borderColor};
        background: ${backgroundColor};
        border-radius: 8px;
        box-sizing: border-box;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        display: flex;
        flex-direction: column;
        position: relative;
        overflow: hidden;
        cursor: move;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        transition: all 0.2s ease;
        user-select: none;
        z-index: 1;
      " onmouseover="this.style.boxShadow='0 4px 16px rgba(34, 157, 234, 0.3)'" 
         onmouseout="this.style.boxShadow='0 2px 8px rgba(0, 0, 0, 0.1)'">
        
        <div style="
          background: ${borderColor};
          color: white;
          font-size: 12px;
          font-weight: 600;
          text-align: center;
          padding: 6px 8px;
          min-height: 28px;
          line-height: 16px;
          box-sizing: border-box;
          display: flex;
          align-items: center;
          justify-content: center;
          border-radius: 6px 6px 0 0;
        ">${nodeName}</div>
        
        <div style="
          flex: 1;
          display: flex;
          flex-direction: column;
          padding: 8px;
          min-height: 0;
        ">
          <div style="
            flex: 1;
            display: flex;
            flex-direction: column;
            justify-content: center;
            font-size: 10px;
            color: #666;
            text-align: center;
            line-height: 12px;
            padding: 4px 0;
          ">
            <div style="color: #999; margin-bottom: 2px; font-size: 10px;">审核时间</div>
            <div style="
              color: #333; 
              font-weight: 500; 
              font-size: 9px;
              max-width: 140px;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
              margin: 0 auto;
            " title="${auditTimeLabel}">${auditTimeLabel}</div>
          </div>
          
          <div style="
            height: 1px;
            background: #ccc;
            margin: 0 8px;
            flex-shrink: 0;
          "></div>
          
          <div style="
            flex: 1;
            display: flex;
            flex-direction: column;
            justify-content: center;
            font-size: 10px;
            color: #666;
            text-align: center;
            line-height: 12px;
            padding: 4px 0;
          ">
            <div style="color: #999; margin-bottom: 2px; font-size: 10px;">审核人员</div>
            <div style="
              color: #333;
              font-weight: 500;
              font-size: 9px;
              max-width: 140px;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
              margin: 0 auto;
            " title="${selectedDataLabel}">${selectedDataLabel}</div>
          </div>
        </div>
      </div>
    `

    // 阻止双击事件冒泡，防止触发文本编辑
    const nodeElement = rootEl.querySelector('.custom-vue-node') as HTMLElement
    if (nodeElement) {
      nodeElement.addEventListener('dblclick', (e) => {
        e.stopPropagation()
        e.preventDefault()
      })

      // 阻止点击事件可能触发的文本编辑
      nodeElement.addEventListener('click', (e) => {
        // 允许单击事件正常传播（用于选中节点），但防止文本编辑
        if (e.detail === 2) {
          // 双击检测
          e.stopPropagation()
          e.preventDefault()
        }
      })
    }
  }

  // 监听属性变化，当属性变化时重新渲染
  componentDidUpdate() {
    if (this.rootEl) {
      this.setHtml(this.rootEl)
    }
  }
}

/**
 * 导出默认配置
 * @returns
 */
export const node = () => {
  /**默认节点 */
  const nodes = [
    {
      id: '10000',
      type: 'start-event',
      x: 100,
      y: 280,
      text: '发起申请',
      properties: {
        r: 45,
      },
    },
    {
      id: '10001',
      type: 'custom-vue-node',
      x: 360,
      y: 280,
      text: '部门审核',
      properties: {
        borderColor: '#229DEA',
        auditTime: null,
        userId: [],
        value: 'dept',
      },
    },
    {
      id: '10002',
      type: 'custom-vue-node',
      x: 620,
      y: 280,
      text: '学校审核',
      properties: {
        borderColor: '#22EA29',
        auditTime: null,
        userId: [],
        value: 'school',
      },
    },
    {
      id: '20000',
      type: 'end-event',
      x: 900,
      y: 280,
      text: '结束',
      properties: {
        r: 45,
      },
    },
  ]
  /**默认边 */
  const edges = [
    {
      id: '30000',
      type: 'EDGE_BEZIER',
      sourceNodeId: '10000',
      targetNodeId: '10001',
    },
    {
      id: '30001',
      type: 'EDGE_BEZIER',
      sourceNodeId: '10001',
      targetNodeId: '10002',
    },
    {
      id: '30002',
      type: 'EDGE_BEZIER',
      sourceNodeId: '10002',
      targetNodeId: '20000',
    },
  ]
  return {
    nodes,
    edges,
  }
}

// 导出自定义节点类型，用于在 LogicFlow 中注册
export const customNodeTypes = {
  'start-event': {
    view: CircleNode,
    model: StartEventModel,
  },
  'end-event': {
    view: CircleNode,
    model: EndEventModel,
  },
  'custom-rect': {
    view: RectNode,
    model: SquareModel,
  },
  'custom-vue-node': {
    view: CustomVueNodeView,
    model: CustomVueNodeModel,
  },
}

// 导出自定义边类型
export const customEdgeTypes = {
  EDGE_BEZIER: {
    view: customBezierEdgeView,
    model: customBezierEdgeModel,
  },
}
